package com.apigen.platform.util;

import lombok.extern.slf4j.Slf4j;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.Random;

/**
 * 验证码工具类
 *
 * @author API Generator Platform
 * @since 2025-09-24
 */
@Slf4j
public class CaptchaUtil {

    private static final String CAPTCHA_CHARS = "ABCDEFGHJKMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz23456789";
    private static final int CAPTCHA_LENGTH = 4;
    private static final int IMAGE_WIDTH = 120;
    private static final int IMAGE_HEIGHT = 40;
    private static final Random RANDOM = new Random();

    /**
     * 生成验证码结果
     */
    public static class CaptchaResult {
        private String code;
        private String imageBase64;

        public CaptchaResult(String code, String imageBase64) {
            this.code = code;
            this.imageBase64 = imageBase64;
        }

        public String getCode() {
            return code;
        }

        public String getImageBase64() {
            return imageBase64;
        }
    }

    /**
     * 生成验证码
     */
    public static CaptchaResult generateCaptcha() {
        // 1. 生成验证码文本
        String captchaCode = generateCaptchaCode();
        
        // 2. 生成验证码图片
        String imageBase64 = generateCaptchaImage(captchaCode);
        
        return new CaptchaResult(captchaCode, imageBase64);
    }

    /**
     * 生成验证码文本
     */
    private static String generateCaptchaCode() {
        StringBuilder code = new StringBuilder();
        for (int i = 0; i < CAPTCHA_LENGTH; i++) {
            code.append(CAPTCHA_CHARS.charAt(RANDOM.nextInt(CAPTCHA_CHARS.length())));
        }
        return code.toString();
    }

    /**
     * 生成验证码图片
     */
    private static String generateCaptchaImage(String code) {
        try {
            // 创建图片
            BufferedImage image = new BufferedImage(IMAGE_WIDTH, IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB);
            Graphics2D g2d = image.createGraphics();

            // 设置抗锯齿
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

            // 填充背景色
            g2d.setColor(getRandomColor(200, 250));
            g2d.fillRect(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);

            // 绘制干扰线
            drawInterferenceLines(g2d);

            // 绘制验证码字符
            drawCaptchaText(g2d, code);

            // 绘制干扰点
            drawInterferencePoints(g2d);

            g2d.dispose();

            // 转换为Base64
            return imageToBase64(image);

        } catch (Exception e) {
            log.error("生成验证码图片失败", e);
            throw new RuntimeException("生成验证码图片失败", e);
        }
    }

    /**
     * 绘制干扰线
     */
    private static void drawInterferenceLines(Graphics2D g2d) {
        for (int i = 0; i < 5; i++) {
            g2d.setColor(getRandomColor(100, 200));
            g2d.setStroke(new BasicStroke(1.0f + RANDOM.nextFloat()));
            int x1 = RANDOM.nextInt(IMAGE_WIDTH);
            int y1 = RANDOM.nextInt(IMAGE_HEIGHT);
            int x2 = RANDOM.nextInt(IMAGE_WIDTH);
            int y2 = RANDOM.nextInt(IMAGE_HEIGHT);
            g2d.drawLine(x1, y1, x2, y2);
        }
    }

    /**
     * 绘制验证码文本
     */
    private static void drawCaptchaText(Graphics2D g2d, String code) {
        String[] fontNames = {"Arial", "Times New Roman", "Courier New", "Verdana"};
        int charWidth = IMAGE_WIDTH / CAPTCHA_LENGTH;
        
        for (int i = 0; i < code.length(); i++) {
            // 随机字体
            String fontName = fontNames[RANDOM.nextInt(fontNames.length)];
            int fontStyle = RANDOM.nextBoolean() ? Font.BOLD : Font.PLAIN;
            int fontSize = 20 + RANDOM.nextInt(8);
            Font font = new Font(fontName, fontStyle, fontSize);
            g2d.setFont(font);

            // 随机颜色
            g2d.setColor(getRandomColor(20, 130));

            // 随机位置和角度
            int x = i * charWidth + RANDOM.nextInt(10) + 10;
            int y = 25 + RANDOM.nextInt(8);
            
            // 随机旋转
            double angle = (RANDOM.nextDouble() - 0.5) * 0.4;
            g2d.rotate(angle, x, y);
            
            g2d.drawString(String.valueOf(code.charAt(i)), x, y);
            
            // 恢复旋转
            g2d.rotate(-angle, x, y);
        }
    }

    /**
     * 绘制干扰点
     */
    private static void drawInterferencePoints(Graphics2D g2d) {
        for (int i = 0; i < 50; i++) {
            g2d.setColor(getRandomColor(50, 200));
            int x = RANDOM.nextInt(IMAGE_WIDTH);
            int y = RANDOM.nextInt(IMAGE_HEIGHT);
            g2d.fillOval(x, y, 1, 1);
        }
    }

    /**
     * 获取随机颜色
     */
    private static Color getRandomColor(int min, int max) {
        int r = min + RANDOM.nextInt(max - min);
        int g = min + RANDOM.nextInt(max - min);
        int b = min + RANDOM.nextInt(max - min);
        return new Color(r, g, b);
    }

    /**
     * 图片转Base64
     */
    private static String imageToBase64(BufferedImage image) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(image, "png", baos);
        byte[] bytes = baos.toByteArray();
        return "data:image/png;base64," + Base64.getEncoder().encodeToString(bytes);
    }

    /**
     * 生成简单的数字验证码（用于测试）
     */
    public static String generateSimpleCaptcha() {
        StringBuilder code = new StringBuilder();
        for (int i = 0; i < 4; i++) {
            code.append(RANDOM.nextInt(10));
        }
        return code.toString();
    }

    /**
     * 验证验证码（忽略大小写）
     */
    public static boolean validateCaptcha(String inputCode, String correctCode) {
        if (inputCode == null || correctCode == null) {
            return false;
        }
        return inputCode.equalsIgnoreCase(correctCode);
    }
}
